//
// Created by yyl on 2021/11/26.
//

#include "TriangleShader.h"


//1. 顶点数组对象(Vertex Array Object, VAO)
GLuint TriangleShader::createVAO() {
    LOGI("createVAO");
    GLuint VAO;
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);
    return VAO;
}

//1. 顶点缓冲对象(Vertex Buffer Objects, VBO)
GLuint TriangleShader::createVBO() {
    LOGI("createVBO");
    float vertices[] = {
            // 位置X   Y   Z    //纹理坐标 S T
            1.0f, 1.0f, 0.0f, 1.0f, 1.0f,   // 右上
            1.0f, -1.0f, 0.0f, 1.0f, 0.0f,  // 右下
            -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // 左下
            -1.0f, 1.0f, 0.0f, 0.0f, 1.0f   // 左上
    };
    GLuint VBO;
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    //位置属性指针XYZ   对应vertex.vert中的变量 layout(location = 0)
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *) 0);
    glEnableVertexAttribArray(0);

    //   对应vertex.vert中的变量 layout(location = 1)
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float),
                          (void *) (3 * sizeof(float)));
    glEnableVertexAttribArray(1);
    return VBO;
}

//2. 索引缓冲对象(Element Buffer Object，EBO，也叫Index Buffer Object，IBO)
//面试：索引缓冲对象:主要解决顶点坐标重复，优化顶点坐标
GLuint TriangleShader::createEBO() {
    // 注意索引从0开始!
    GLuint indices[] = {
            0, 1, 2, // 第一个三角形
            0, 2, 3  // 第二个三角形
    };
    GLuint EBO;
    glGenBuffers(1, &EBO);
    //5.复制我们的索引数组到一个索引缓冲中，供OpenGL使用
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    //把索引数据复制到缓冲的内存中
    //把[indices]数据 复制到缓冲的内存 给<缓冲buffer>然后上面的<缓冲buffer>EBO就有值了
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    return EBO;
}

void TriangleShader::Init() {
    if (!isInit) {
        isInit = true;
//        glEnable(GL_DEPTH_TEST);
//        auto str = glGetString(GL_EXTENSIONS);
//        LOGI("查看设备所支持的扩展:%s", str);
        VAO = createVAO();
        VBO = createVBO();
        createEBO();
        createShaderFromFile();
        createTexture();
        bindTextureImage();

    }
}

void TriangleShader::Draw(int screenW, int screenH) {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.0, 0.0, 0.0, 1.0);
    if (programID) {
        glUseProgram(programID);
//        glm::mat4 pvm = MatrixConvert::convert(transformMatrix, screenW, screenH);
        glm::mat4 pvm = MatrixConvert::convertOrtho(transformMatrix);
        GLUtils::setMat4(programID, "PVM", pvm);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, textureID);
        glBindVertexArray(VAO);
        //EBO填充
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
        //解绑VAO
        glBindVertexArray(GL_NONE);
        glUseProgram(GL_NONE);
    }

}



